﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.UI.WebControls;
using Intellego.Web.ValidationEngine;
using MIAP.Entidades;
using MIAP.Entidades.Enums;
using MIAP.Negocio;
using MIAP.Negocio.Utiles;
using MIAPWEB.Common;

namespace MIAPWEB.Forms
{
    /// <summary>
    /// Clase de la vista Ejecución de Proyectos.
    /// </summary>
    public partial class EjecutaProyecto : PageBase
    {
        #region Campos

        /// <summary>
        /// Almacena la ruta de los paquetes.
        /// </summary>
        string ruta = string.Empty;

        /// <summary>
        /// Clase de negocio para las operaciones de comunes negocio.
        /// </summary>
        ComunesNegocio comunesNegocio;

        /// <summary>
        /// Clase de negocio para las operaciones de ejecución proyectos negocio.
        /// </summary>
        EjecucionProyectosNegocio ejecucionProyectosNegocio;

        #endregion

        #region Propiedades

        /// <summary>
        ///  Obtiene o establece los filtros para la búsqueda.
        /// </summary>
        public ArchivoAsociadoProyectoInfo ArchivoAsociadoFilters
        {
            get
            {
                return (ArchivoAsociadoProyectoInfo)this.ViewState["ArchivoAsociadoFilters"];
            }

            set
            {
                this.ViewState["ArchivoAsociadoFilters"] = value;
            }
        }

        /// <summary>
        /// registros busqueda
        /// </summary>
        private List<ArchivoCargadoInfo> DataSourcePeriodo
        {
            get
            {
                if (this.ViewState["DataSourcePeriodo"] == null)
                {
                    this.ViewState["DataSourcePeriodo"] = new List<ArchivoCargadoInfo>();
                }

                return this.ViewState["DataSourcePeriodo"] as List<ArchivoCargadoInfo>;
            }

            set
            {
                this.ViewState["DataSourcePeriodo"] = value;
            }
        }

        /// <summary>
        /// registros busquedaObligatorio
        /// </summary>
        private List<ArchivoAsociadoProyectoInfo> DataSourceArchivosObligatorios
        {
            get
            {
                if (this.ViewState["DataSourceArchivosObligatorios"] == null)
                {
                    this.ViewState["DataSourceArchivosObligatorios"] = new List<ArchivoAsociadoProyectoInfo>();
                }

                return this.ViewState["DataSourceArchivosObligatorios"] as List<ArchivoAsociadoProyectoInfo>;
            }

            set
            {
                this.ViewState["DataSourceArchivosObligatorios"] = value;
            }
        }

        /// <summary>
        /// registros busqueda no obligatorios
        /// </summary>
        private List<ArchivoAsociadoProyectoInfo> DataSourceArchivosNoObligatorios
        {
            get
            {
                if (this.ViewState["DataSourceArchivosNoObligatorios"] == null)
                {
                    this.ViewState["DataSourceArchivosNoObligatorios"] = new List<ArchivoAsociadoProyectoInfo>();
                }

                return this.ViewState["DataSourceArchivosNoObligatorios"] as List<ArchivoAsociadoProyectoInfo>;
            }

            set
            {
                this.ViewState["DataSourceArchivosNoObligatorios"] = value;
            }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Inicializa una instancia de <see cref="EjecutaProyecto"/>
        /// </summary>
        public EjecutaProyecto()
        {
            this.comunesNegocio = new ComunesNegocio();
            this.ejecucionProyectosNegocio = new EjecucionProyectosNegocio();
        }

        #endregion

        #region Eventos

        /// <summary>
        /// Evento que se ejecuta al cargar la página.
        /// </summary>
        /// <param name="sender">Objeto que invoca al evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            int pageSize = Convert.ToInt32(new ConfiguracionNegocio().GetNumeroPaginasGrid().Descripcion);
            this.grdArchivosNoObligatorios.PageSize = pageSize;
            this.grdArchivosObligatorios.PageSize = pageSize;
            this.grdCargasPeriodo.PageSize = pageSize;

            if (!this.IsPostBack)
            {
                this.ArchivoAsociadoFilters = new ArchivoAsociadoProyectoInfo();

                this.GetProyectos();
                this.GetMeses();
                this.GetAños();

                this.Search();
            }
            this.InitValidation();
        }

        /// <summary>
        /// Método ejecutado al dar click al botón buscar. Obtiene los archivos obligatorios, los no obligatorios y las cargas de archivos dependiendo de los filtros.
        /// </summary>
        /// <param name="sender">Objeto que invoca el evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void btnBuscar_Click(object sender, EventArgs e)
        {
            this.Search();
        }

        /// <summary>
        /// Método ejecutado al dar click al botón Ejecutar Proyecto.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnEjecutarProyecto_Click(object sender, EventArgs e)
        {
            if (!this.ValidaInicioEjecucion()) return;

            var anio = this.ddlAño.SelectedItem.Text;
            var mes = this.ddlMes.SelectedItem.Value;
            var user = AppSessionManager.Instance.Usuario;
            var proyecto = this.ddlProyecto.SelectedItem.Text;

            if (
                this.ejecucionProyectosNegocio.ValidaEjecucionEnProceso(
                    Convert.ToInt32(this.ddlProyecto.SelectedItem.Value), Convert.ToInt32(anio), Convert.ToInt32(this.ddlMes.SelectedItem.Value)))
            {
                this.ShowMessage(GetGlobalResourceObject("Strings", "EjecucionPaqueteProceso").ToString());
                return;
            }
            var nombrePAqueteProy =
              this.ejecucionProyectosNegocio.GetProyectoById(Convert.ToInt32(this.ddlProyecto.SelectedValue))
                  .PaqueteCarga;

            using (var prueba = new ExecutorDtsx( nombrePAqueteProy, proyecto, string.Empty))
            {
                var variables = prueba.GetUserVariables();
                var valores = new VariablesConocidas
                    {
                        Año = anio,
                        Mes = mes,
                        User = user,
                        Filename = nombrePAqueteProy,
                        Version = string.Empty
                    };
                prueba.SetValoresConocidos(valores);
                if (prueba.ExistenValoresVacios())
                {
                    wucVariablesDtsx.AdddControls(variables, prueba.ValoresYVariables);
                    VariablesModalPopupExtender.Show();
                }
                else
                {

                    valores.IdBitacora = this.RegistraEjecucion();
                    prueba.SetValoresConocidos(valores);
                    if (!prueba.ExecuteDtsx(prueba.ValoresYVariables))
                    {
                        this.wucListaErrores.ListaErrores = prueba.Errores;
                        this.ListaErroresPanelModalPopupExtender.Show();
                        this.comunesNegocio.SetProcesoError(valores.IdBitacora, AppSessionManager.Instance.Usuario);
                        return;
                    }
                    this.ShowMessageGuardado();
                }
            }
        }

        protected void EjecutarPaquete_btnClick(object sender, EventArgs e)
        {

            var proyecto = this.ddlProyecto.SelectedItem.Text;
            var nombrePAqueteProy =
                this.ejecucionProyectosNegocio.GetProyectoById(Convert.ToInt32(this.ddlProyecto.SelectedValue))
                    .PaqueteCarga;
            using (var executor = new ExecutorDtsx(nombrePAqueteProy,this.ddlProyecto.SelectedItem.Text,string.Empty))
            {
                var valores = wucVariablesDtsx.GetValores();

                var idbit = this.RegistraEjecucion();
                var variables = new VariablesConocidas {IdBitacora = idbit};
                executor.SetValoresConocidos(variables);
                if (!executor.ExecuteDtsx(valores))
                {
                    this.wucListaErrores.ListaErrores = executor.Errores;
                    this.ListaErroresPanelModalPopupExtender.Show();
                    this.comunesNegocio.SetProcesoError(idbit, AppSessionManager.Instance.Usuario);
                    return;
                }
                this.ShowMessageGuardado();

            }
        }

        /// <summary>
        /// Método ejecutado al dar click al botón salir. Redirecciona a la página principal.
        /// </summary>
        /// <param name="sender">Objeto que invoca el evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void btnSalir_Click(object sender, EventArgs e)
        {
            Response.Redirect(Common.AppUrls.Default);
        }

        /// <summary>
        /// Evento que se ejecuta cuando se cambia de página en el grid.
        /// </summary>
        /// <param name="sender">Objeto que invoca el evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void grdArchivosObligatorios_OnPageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            this.grdArchivosObligatorios.PageIndex = e.NewPageIndex;
            this.grdArchivosObligatorios.DataSource = this.DataSourceArchivosObligatorios;
            this.grdArchivosObligatorios.DataBind();
        }

        /// <summary>
        /// Evento que se ejecuta cuando se cambia de página en el grid.
        /// </summary>
        /// <param name="sender">Objeto que invoca el evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void grdArchivosNoObligatorios_OnPageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            this.grdArchivosNoObligatorios.PageIndex = e.NewPageIndex;
            this.grdArchivosNoObligatorios.DataSource = this.DataSourceArchivosNoObligatorios;
            this.grdArchivosNoObligatorios.DataBind();
        }

        /// <summary>
        /// Evento que se ejecuta cuando se cambia de página en el grid.
        /// </summary>
        /// <param name="sender">Objeto que invoca el evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void grdCargasPeriodo_OnPageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            this.grdCargasPeriodo.PageIndex = e.NewPageIndex;
            this.grdCargasPeriodo.DataSource = this.DataSourcePeriodo;
            this.grdCargasPeriodo.DataBind();
        }

        #endregion

        #region Métodos

        /// <summary>
        /// Obtiene todos los proyectos.
        /// </summary>
        public void GetProyectos()
        {
            this.ddlProyecto.DataSource = AppSessionManager.Instance.GetProyectosByPagina(AppUrls.EjecucionProyectos);
            this.ddlProyecto.DataBind();

            this.comunesNegocio.SetSeleccionar(this.GetGlobalResourceObject("strings", "Seleccionar").ToString(), this.ddlProyecto);
        }

        /// <summary>
        /// Obtiene los meses.
        /// </summary>
        private void GetMeses()
        {
            this.ddlMes.DataSource = this.comunesNegocio.GetMeses();
            this.ddlMes.DataBind();
            this.comunesNegocio.SetSeleccionar(this.GetGlobalResourceObject("strings", "Seleccionar").ToString(), this.ddlMes);
        }

        /// <summary>
        /// Obtiene una lista de 10 años a partir del actual.
        /// </summary>
        private void GetAños()
        {
            this.ddlAño.DataSource = this.comunesNegocio.GetAños();
            this.ddlAño.DataBind();
            this.comunesNegocio.SetSeleccionar(this.GetGlobalResourceObject("strings", "Seleccionar").ToString(), this.ddlAño);
        }

        /// <summary>
        /// Obtiene los archivos obligatorios y los no obligatorios.
        /// </summary>
        private void GetArchivosObligatoriosNoObligatorios()
        {
            this.DataSourceArchivosObligatorios = this.ejecucionProyectosNegocio.GetArchivosObligatoriosAndNoObligatorios(this.ArchivoAsociadoFilters, true);
            this.grdArchivosObligatorios.DataSource = this.DataSourceArchivosObligatorios;
            this.grdArchivosObligatorios.DataBind();

            this.DataSourceArchivosNoObligatorios = this.ejecucionProyectosNegocio.GetArchivosObligatoriosAndNoObligatorios(this.ArchivoAsociadoFilters, false);
            this.grdArchivosNoObligatorios.DataSource = this.DataSourceArchivosNoObligatorios;
            this.grdArchivosNoObligatorios.DataBind();
        }

        /// <summary>
        /// Obtiene los filtros y busca los archivos obligatorios y no obligatorios.
        /// </summary>
        private void Search()
        {
            this.GetFilters();
            this.GetArchivosObligatoriosNoObligatorios();
            this.GetCargasRealizadas();
        }

        /// <summary>
        /// Obtiene los filtros.
        /// </summary>
        private void GetFilters()
        {
            this.ArchivoAsociadoFilters.IdProyecto = int.Parse(ddlProyecto.SelectedValue) <= default(int) ? this.ArchivoAsociadoFilters.IdProyecto = null : int.Parse(ddlProyecto.SelectedValue);
            this.ArchivoAsociadoFilters.Año = int.Parse(ddlAño.SelectedValue) <= default(int) ? this.ArchivoAsociadoFilters.Año = null : int.Parse(ddlAño.SelectedValue);
            this.ArchivoAsociadoFilters.Mes = int.Parse(ddlMes.SelectedValue) <= default(int) ? this.ArchivoAsociadoFilters.Mes = null : int.Parse(ddlMes.SelectedValue);
        }

        /// <summary>
        /// Obtiene las cargas y recargas realizadas de los archivos.
        /// </summary>
        private void GetCargasRealizadas()
        {
            this.DataSourcePeriodo = this.ejecucionProyectosNegocio.GetCargasRealizadasByPeriodo(this.ArchivoAsociadoFilters);
            this.grdCargasPeriodo.DataSource = this.DataSourcePeriodo;
            this.grdCargasPeriodo.DataBind();
        }

        /// <summary>
        /// Agregar las validaciones para los campos requeridos.
        /// </summary>
        private void InitValidation()
        {
            var ddlpermitido = this.GetGlobalResourceObject("strings", "ErrorDropDownRequerido").ToString();

            var ruleIdProyecto = new ValidationRule(this.ddlProyecto);
            var ruleAño = new ValidationRule(this.ddlAño);

            ruleIdProyecto.NotEmpty(ddlpermitido);
            ruleAño.NotEmpty(ddlpermitido);

            this.ValidationEngine.Add(ruleIdProyecto);
            this.ValidationEngine.Add(ruleAño);
        }

        /// <summary>
        /// Valida si existen las condiciones para ejecutar el proyecto o no.
        /// </summary>
        /// <returns></returns>
        private bool ValidaInicioEjecucion()
        {
            var IdProyecto = int.Parse(ddlProyecto.SelectedValue) <= default(int) ? this.ArchivoAsociadoFilters.IdProyecto = null : int.Parse(ddlProyecto.SelectedValue);
            var Año = int.Parse(ddlAño.SelectedValue) <= default(int) ? this.ArchivoAsociadoFilters.Año = null : int.Parse(ddlAño.SelectedValue);
            var Mes = int.Parse(ddlMes.SelectedValue) <= default(int) ? this.ArchivoAsociadoFilters.Mes = null : int.Parse(ddlMes.SelectedValue);

            if (IdProyecto != this.ArchivoAsociadoFilters.IdProyecto || this.ArchivoAsociadoFilters.Año != Año ||
                this.ArchivoAsociadoFilters.Mes != Mes)
            {
                this.ShowMessage(GetGlobalResourceObject("Strings", "FaltaValidarInformacion").ToString());
                return false;
            }
        
            if (grdArchivosObligatorios.Rows.Cast<GridViewRow>().Any(row => row.Cells[3].Text.ToLower() == Enum.GetName(typeof(SiNo), SiNo.No).ToLower()))
            {
                this.ShowMessage(GetGlobalResourceObject("Strings", "CargaArchivosFaltantes").ToString());
                return false;
            }
            
            foreach (ArchivoAsociadoProyectoInfo archivo in DataSourceArchivosObligatorios)
            {
                if (archivo.Versionable)
                {
                    string nombreVersion = this.ejecucionProyectosNegocio.GetNombreVersionValidaArchivo(archivo.IdArchivo.Value);

                    if (nombreVersion == null)
                    {
                        this.ShowMessage(GetGlobalResourceObject("Strings", "EjecutaPreoyecto_ArchivoSinVersionValida").ToString());
                        return false;
                    }
                }
            }
            
            return true;
        }

        /// <summary>
        /// registra la ejecucion del paquete en la base de datos
        /// </summary>
        private int RegistraEjecucion()
        {
            int idBitacoraGral;
            var usuario = new UsuarioInfo
            {
                AliasUsuario = AppSessionManager.Instance.Usuario,
                IdUsuario = AppSessionManager.Instance.IdUsuario
            };
            var loProyecto = new ListaInfo
            {
                Año = Convert.ToInt32(this.ddlAño.SelectedItem.Text),
                Mes = Convert.ToInt32(this.ddlMes.SelectedItem.Value),
                IdProyecto = Convert.ToInt32(this.ddlProyecto.SelectedValue),
            };
            idBitacoraGral=this.ejecucionProyectosNegocio.EjecutaProyecto(loProyecto, usuario);
           
            return idBitacoraGral;        
        }

        private void ShowMessageGuardado()
        {
            var mensaje = String.Format(this.GetGlobalResourceObject("strings", "EjecucionProyecto").ToString(), this.ddlProyecto.SelectedItem.Text);
            this.ShowMessage(mensaje, this.PreviousPage);
        }

        #endregion
    }
}